package com.ruoyi.system.service.impl;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.*;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.sdk.AdminConfig;
import cn.wildfirechat.sdk.GroupAdmin;
import cn.wildfirechat.sdk.MessageAdmin;
import cn.wildfirechat.sdk.UserAdmin;
import cn.wildfirechat.sdk.model.IMResult;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.MessageQuery;
import com.ruoyi.system.dto.GroupAssistantMessageHistoryDTO;
import com.ruoyi.system.dto.GroupSendMessage;
import com.ruoyi.system.dto.TMessagesDTO;
import com.ruoyi.system.imDomain.TextMessageContent;
import com.ruoyi.system.mapper.TGroupMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ruoyi.system.mapper.TMessagesMapper;
import com.ruoyi.system.mapper.TUserMessagesMapper;
import com.ruoyi.system.service.ITMessagesService;
import com.ruoyi.system.utils.ShardingTableUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * 消息】Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-08-18
 */
@Service
@Slf4j
public class TMessagesServiceImpl implements ITMessagesService 
{
    @Autowired
    private TMessagesMapper tMessagesMapper;

    @Autowired
    private TGroupMapper groupMapper;
    
    @Autowired
    private TUserMessagesMapper tUserMessagesMapper;
    @Value("${admin:admin}")
    private String admin;

    /**
     * 查询消息】
     * 
     * @param id 消息】主键
     * @return 消息】
     */
    @Override
    public TMessages selectTMessagesById(Long id)
    {
        return tMessagesMapper.selectTMessagesById(id);
    }

    /**
     * 查询消息列表*
     * @param query 消息
     * @return 消息
     */
    @Override
    public TableDataInfo selectTMessagesList(MessageQuery query, int pageNum, int pageSize)
    {
        List<TMessages> resultList = new ArrayList<>();
        long totalCount;
        int offset = Math.max(0, (pageNum - 1) * pageSize);
        // 构造时间范围内的分表集合
        List<String> tableNames = buildUnionTablesByDateRange(query);
        String tableName = tableNames.get(0);
        totalCount = tMessagesMapper.countUnionMessages(query, tableName);
        resultList = tMessagesMapper.selectUnionMessages(query, tableName, offset, pageSize);
        // 贴合展示，补充用户名信息
        List<TMessagesDTO> res = new ArrayList<>();
        for (TMessages messages : resultList) {
            TMessagesDTO tMessagesDTO = new TMessagesDTO();
            Integer type = enrichMessageWithUserInfo(messages,tMessagesDTO);
            BeanUtils.copyProperties(messages,tMessagesDTO);
            tMessagesDTO.setTargetType(type);
            tMessagesDTO.setData(messages.getSearchableKey());
            res.add(tMessagesDTO);
        }
        TableDataInfo dataTable = new TableDataInfo();
        dataTable.setRows(res);
        dataTable.setTotal(totalCount);
        dataTable.setCode(200);
        dataTable.setMsg("查询成功");
        return dataTable;
    }


    /**
     * 分页查询消息列表（支持分表分页）
     * 可以查询指定用户的消息，也可以查询所有用户的消息
     * 
     * @param query 查询条件
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页结果
     */
    @Override
    public TableDataInfo selectTMessagesListWithPaging(MessageQuery query, int pageNum, int pageSize)
    {
        // 必填校验：type、beginTime、endTime（uid 可选）
        if (query.getType() == null) {
            throw new IllegalArgumentException("type不能为空");
        }
        if (query.getBeginTime() == null || query.getEndTime() == null) {
            throw new IllegalArgumentException("开始/结束时间不能为空");
        }
        // 规范化时间范围：确保 beginTime <= endTime
        if (query.getBeginTime().after(query.getEndTime())) {
            Date tmp = query.getBeginTime();
            query.setBeginTime(query.getEndTime());
            query.setEndTime(tmp);
        }
        List<TMessages> resultList = new ArrayList<>();
        Long totalCount = null;
        // 当未传 uid 时，走全局联合分表查询；传了 uid 则走用户分表关系
        if (query.getUid() == null || query.getUid().trim().isEmpty()) {
            int offset = Math.max(0, (pageNum - 1) * pageSize);
            List<String> tableNames = buildUnionTablesByDateRange(query);
            String tableName = tableNames.get(0);
            totalCount = tMessagesMapper.countUnionMessages(query, tableName);
            resultList = tMessagesMapper.selectUnionMessages(query, tableName, offset, pageSize);

        } else {
            // 1) 计算用户消息分表名（MySQL环境）
            String userMessagesTableName = ShardingTableUtils.getUserMessagesTableName(query.getUid(), false);

            // 2) 分页查询用户消息关系（使用：_uid、_type、_dt范围），按_dt倒序
            PageHelper.startPage(pageNum, pageSize);
            List<TUserMessages> userMessagesList = tUserMessagesMapper.selectTUserMessagesList(query, userMessagesTableName);
            PageInfo<TUserMessages> pageInfo = new PageInfo<>(userMessagesList);

            // 3) 批量按分表查询消息详情，减少N+1
            java.util.Map<String, List<Long>> tableIdMap = new java.util.HashMap<>();
            for (TUserMessages um : userMessagesList) {
                if (um.getDt() == null || um.getMid() == null) {
                    continue;
                }
                String messagesTableName = ShardingTableUtils.getMessagesTableName(um.getDt(), false);
                tableIdMap.computeIfAbsent(messagesTableName, k -> new ArrayList<>()).add(Long.valueOf(um.getMid()));
            }
            for (java.util.Map.Entry<String, List<Long>> entry : tableIdMap.entrySet()) {
                List<TMessages> subList = tMessagesMapper.selectTMessagesByIds(entry.getValue(), entry.getKey());
                if (subList != null && !subList.isEmpty()) {
                    resultList.addAll(subList);
                }
            }
            // 4) 合并后按时间倒序
            resultList.sort((a, b) -> {
                if (a.getDt() == null && b.getDt() == null) return 0;
                if (a.getDt() == null) return 1;
                if (b.getDt() == null) return -1;
                return b.getDt().compareTo(a.getDt());
            });
            totalCount = pageInfo.getTotal();

        }
        List<TMessagesDTO> res = new ArrayList<>();
        // 5) 贴合展示，补充用户名信息
        for (TMessages messages : resultList) {
            TMessagesDTO tMessagesDTO = new TMessagesDTO();
            Integer type = enrichMessageWithUserInfo(messages,tMessagesDTO);
            BeanUtils.copyProperties(messages,tMessagesDTO);
            tMessagesDTO.setTargetType(type);
            tMessagesDTO.setData(messages.getSearchableKey());
            res.add(tMessagesDTO);
        }

        // 6) 封装分页结果（总数来源于用户消息关系分页）
        TableDataInfo dataTable = new TableDataInfo();
        dataTable.setRows(res);
        dataTable.setTotal(totalCount);
        dataTable.setCode(200);
        dataTable.setMsg("查询成功");
        return dataTable;
    }

    private List<String> buildUnionTablesByDateRange(MessageQuery query) {
        List<String> tableNames = new ArrayList<>();
        Date begin = query.getBeginTime() != null ? query.getBeginTime() : null;
        Date end = query.getEndTime() != null ? query.getEndTime() : null;;
        if (begin == null || end == null) {
            // 无时间范围，默认查询所有36张分表
            for (int i = 0; i < 36; i++) {
                tableNames.add("t_messages_" + i);
            }
            return tableNames;
        }
        // 规范化，确保 begin <= end
        if (begin.after(end)) {
            Date tmp = begin;
            begin = end;
            end = tmp;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(begin);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(end);
        // 遍历月份（包含端点月份）
        while (cal.get(Calendar.YEAR) < endCal.get(Calendar.YEAR)
                || (cal.get(Calendar.YEAR) == endCal.get(Calendar.YEAR)
                    && cal.get(Calendar.MONTH) <= endCal.get(Calendar.MONTH))) {
            int year = cal.get(Calendar.YEAR);
            int month = cal.get(Calendar.MONTH) + 1; // Calendar 月份从0开始
            String tbl = ShardingTableUtils.getMessagesTableName(year, month, false);
            if (!tableNames.contains(tbl)) {
                tableNames.add(tbl);
            }
            cal.add(Calendar.MONTH, 1);
        }
        return tableNames;
    }


    private Integer enrichMessageWithUserInfo(TMessages message, TMessagesDTO tMessagesDTO) {
        if (message == null) return null;
        int type = 1 ;
        try {
            IMResult<InputOutputUserInfo> fromUserResult = UserAdmin.getUserByUserId(message.getFrom());
            if (fromUserResult != null && fromUserResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                message.setFrom(fromUserResult.getResult().getDisplayName());
                tMessagesDTO.setFromMobile(fromUserResult.getResult().getMobile());
            }
            IMResult<InputOutputUserInfo> toUserResult = UserAdmin.getUserByUserId(message.getTarget());
            if (toUserResult != null && toUserResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                message.setTarget(toUserResult.getResult().getDisplayName());
                tMessagesDTO.setTargetMobile(toUserResult.getResult().getMobile());
            }else {
                QueryWrapper<TGroup> wrapper = new QueryWrapper<>();
                wrapper.select("id","_name");
                wrapper.eq("_gid",message.getTarget());
                TGroup tGroup = groupMapper.selectOne(wrapper);
                if (tGroup != null ) {
                    message.setTarget(tGroup.getName());
                    type = 2;
                }
            }
        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage());
        }
        return type;
    }
    /**
     * 新增消息】
     * 
     * @param tMessages 消息】
     * @return 结果
     */
    @Override
    public int insertTMessages(TMessages tMessages)
    {
        return tMessagesMapper.insertTMessages(tMessages);
    }

    /**
     * 修改消息】
     * 
     * @param tMessages 消息】
     * @return 结果
     */
    @Override
    public int updateTMessages(TMessages tMessages)
    {
        return tMessagesMapper.updateTMessages(tMessages);
    }

    /**
     * 批量删除消息
     * 
     * @param ids 需要删除的消息】主键
     * @return 结果
     */
    @Override
    public int deleteTMessagesByIds(Long[] ids)
    {
        for (Long id : ids) {
            try {
                MessageAdmin.deleteMessage(id);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return 1;
    }

    @Override
    public Boolean broadcastMessage(String text) {
        TextMessageContent textMessageContent = new TextMessageContent(text);
        MessagePayload payload = textMessageContent.encode();
        try {
            IMResult<BroadMessageResult> resultBroadcastMessage = MessageAdmin.broadcastMessage(admin, 0, payload);
            if (resultBroadcastMessage != null && resultBroadcastMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                log.info("broad message success, send message to " + resultBroadcastMessage.getResult().getCount() + " users");
                // 保存群发文本数据
                SendHistory sendHistory = new SendHistory();
                sendHistory.setTargetType(ProtoConstants.ConversationType.ConversationType_Private);
                sendHistory.setSenderId(admin);
                sendHistory.setContent(text);
                sendHistory.setSendTime(LocalDateTime.now());
                sendHistory.setStatus(1);
                sendHistory.setMsgUid(resultBroadcastMessage.getResult().getMessageUid());
                sendHistory.setCreatedAt(LocalDateTime.now());
                sendHistory.setCategory(1);
                tMessagesMapper.insertSendMessage(sendHistory);
            } else {
                log.info("broad message failure");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return true;
    }

    @Override
    public Boolean groupMessage( GroupSendMessage message) {
        for (String id : message.getIds()) {
            String sender = admin;
            Conversation conversation = new Conversation();
            conversation.setTarget(id);
            conversation.setType(ProtoConstants.ConversationType.ConversationType_Group);
            //测试发送文本消息
            TextMessageContent textMessageContent = new TextMessageContent(message.getText());
            //消息转成Payload并发送
            MessagePayload payload = textMessageContent.encode();
            try {
                IMResult<SendMessageResult> resultSendMessage = MessageAdmin.sendMessage(sender, conversation, payload, null);
                if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
                    // 保存群发文本数据
                    SendHistory sendHistory = new SendHistory();
                    sendHistory.setTarget(id);
                    sendHistory.setTargetType(ProtoConstants.ConversationType.ConversationType_Group);
                    sendHistory.setSenderId(sender);
                    sendHistory.setContent(message.getText());
                    sendHistory.setSendTime(LocalDateTime.now());
                    sendHistory.setStatus(1);
                    sendHistory.setMsgUid(resultSendMessage.getResult().getMessageUid());
                    sendHistory.setCreatedAt(LocalDateTime.now());
                    sendHistory.setCategory(2);
                    tMessagesMapper.insertSendMessage(sendHistory);
                    log.info("send message success");
                } else {
                    log.info("send message failure");

                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return true;
    }

    @Override
    public List<SendHistory> sendGroupMessageList() {
        return tMessagesMapper.getSendGroupMessageList(2);
    }

    @Override
    public List<TMessages> exportTMessagesList(TMessages tMessages) {
        List<TMessages> resultList = new ArrayList<>();
        // 计算用户消息表名（MySQL环境）
        String userMessagesTableName = ShardingTableUtils.getUserMessagesTableName(tMessages.getQueryUserId(), false);
        // 查询用户消息记录
        List<TUserMessages> userMessagesList = tUserMessagesMapper.selectTUserMessagesByUserId(tMessages.getQueryUserId(), userMessagesTableName);

        // 根据用户消息记录查询具体消息
        for (TUserMessages userMessage : userMessagesList) {
            // 计算消息表名（根据消息时间，MySQL环境）
            String messagesTableName = ShardingTableUtils.getMessagesTableName(new Date(),false);
            // 查询具体消息
            TMessages message = tMessagesMapper.selectTMessagesById(Long.valueOf(userMessage.getMid()), messagesTableName);
            if (message != null) {
                resultList.add(message);
            }
        }
        for (TMessages messages : resultList) {
            // 获取用户信息
            enrichMessageWithUserInfo(messages,null);
        }
        return resultList;
    }

    @Override
    public List<SendHistory> broadcastMessageList() {
        return tMessagesMapper.getSendGroupMessageList(1);
    }

    @Override
    public void insertGroupAssistantMessageHistory(GroupAssistantMessageHistory history) {
        tMessagesMapper.insertGroupAssistantMessageHistory(history);
    }

    @Override
    public List<TUser> getUserNameByUserIds(String[] split) {
        return tMessagesMapper.getUserNameByUserIds(split);
    }

    @Override
    public List<GroupAssistantMessageHistoryDTO> getGroupAssistantMessageHistory(String id) {
        return tMessagesMapper.getGroupAssistantMessageHistory(id);
    }

    @Override
    public int deleteGroupAssistantMessageHistory(String id) {
        return tMessagesMapper.deleteGroupAssistantMessageHistory(id);
    }
}
